using System;
using System.Collections.Generic;

// http://www.zvon.org/comp/r/tut-XPath_1.html#intro

namespace SharpObjects.XpathToObjects
{
    public class XPathParser : IXPathParser
    {
        private static readonly char[] delimiters = { '/' };

        public List<PathElement> Parse(string path)
        {
            if(path == null || path.Trim().Length == 0)
            {
                throw new ArgumentException("XPath must not be null or empty");
            }

            List<PathElement> pathElements = new List<PathElement>();

            if(path.Length > 1 && path[0] == '/' && path[1] == '/')
            {
                PathElement pathElement = new PathElementAnyPlace("//");
                pathElements.Add(pathElement);
                path = path.Substring(2);
            }
            else if(path.Length > 0 && path[0] == '/')
            {
                PathElement pathElement = new PathElementRoot("/");
                pathElements.Add(pathElement);
                path = path.Substring(1);
            }
            //else
            //{
            //    PathElement pathElement = new PathElementRoot("/");
            //    pathElements.Add(pathElement);
            //}
                
            string[] elements = path.Split(delimiters);

            foreach (string element in elements)
            {
                PathElement pathElement;

                if(element.Length > 0 && element[0] == '@')
                {
                    pathElement = new PathElementObject(element) {IsAttribute = true, Name = element.Substring(1)};
                }
                else if(element.Length == 1 && element[0] == '*')
                {
                    pathElement = new PathElementAnyName(element);
                }
                else if(element.Length > 0 && element[element.Length - 1] == ']')
                {
                    string condition = element.Substring(0, element.Length - 1);
                    int ind = element.IndexOf('[');
                    condition = condition.Substring(ind + 1);

                    int n;

                    if (int.TryParse(condition, out n))
                    {
                        pathElement = new PathElementObject(element){ Name = element.Substring(0, ind), Index = n };
                    }
                    else
                    {
                        pathElement = new PathElementObject(element){ Name = element.Substring(0, ind), Condition = condition };
                    }
                }
                else
                {
                    pathElement = new PathElementObject(element){ Name = element};
                }

                pathElements.Add(pathElement);
            }

            return pathElements;
        }
    }
}